package com.imooc;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.util.*;


/**
 * <p>
 * mongo使用方法
 * </p>
 *
 * @author gzj
 * @since 2022/6/20
 */
@Service
public class Mongo {

    private final String COLLECTION_NAME = "test";

    @Autowired
    private MongoTemplate mongoTemplate;


    /**
     * 新增
     */
    public void insert(Entity entity) {
        mongoTemplate.insert(entity, COLLECTION_NAME);
    }

    /**
     * 修改
     */
    public void update(Entity entity) {
        Query query = Query.query(Criteria.where("_id").is(entity.get_id()));
        Update update = Update.update("name", entity.getName()).set("age", entity.getAge()).set("tel", entity.getTel());
        mongoTemplate.updateFirst(query, update, COLLECTION_NAME);
    }

    /**
     * 删除
     */
    public void del(Entity entity) {
        Query query = Query.query(Criteria.where("_id").is(entity.get_id()));
        mongoTemplate.remove(query, Entity.class, COLLECTION_NAME);
    }

    /**
     * 查询(分页)
     */
    public Map<String, Object> findAllByPage(Entity entity, Long page, Integer pageSize) {
        //页码需要从0开始
        Long pageNum = page - 1;
        Query query = new Query();
        /**
         *  query.addCriteria(Criteria.where("_id").is(entity.get_id()))...;
         *  数组字段直接is就可以了
         *  如果是json字段  key值 =  字段名称.字段内属性名称 例: name.name
         *  （子文档查询）数组字段如果多个条件需要用elemMatch连接 例：Criteria.where("字段名称").elemMatch(Criteria.where("字段内属性名称").is("值").and("字段内属性名称").is("值")
         */
        Criteria criteria = new Criteria();
        criteria.orOperator(
                Criteria.where("_id").is(entity.get_id()),
                Criteria.where("name").regex("^.*" + entity.getName() + ".*$")
        );
        query.addCriteria(criteria);
        //子文档查询
        query.addCriteria(Criteria.where("children").elemMatch(Criteria.where("interest").is("兴趣").and("hobby").is("艾蒿")));
        query.with(new Sort(Sort.Direction.DESC, "updateTime"));
        query.skip((long) pageNum * pageSize).limit(pageSize);
        long count = mongoTemplate.count(query, Entity.class, COLLECTION_NAME);
        List<Entity> List = mongoTemplate.find(query, Entity.class, COLLECTION_NAME);
        Map<String, Object> data = new HashMap<>(3);
        Long totalPage = count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
        //内容
        data.put("rows", List);
        //总数
        data.put("total", count);
        //总页数
        data.put("totalPage", totalPage);
        return data;
    }

    /**
     * 查询(分页)
     */
    public Map<String, Object> findAllByPage2(Entity entity, Long page, Integer pageSize) {
        //页码需要从0开始
        Long pageNum = page - 1;
        long count = 0;
        List<AggregationOperation> operations = new ArrayList<>();

        Criteria criteria = new Criteria();
        criteria.orOperator(
                Criteria.where("_id").is(entity.get_id()),
                Criteria.where("name").regex(".*" + entity.getName() + ".*")
                );
        operations.add(Aggregation.match(criteria));
        //时间<=传入时间
        operations.add(Aggregation.match(Criteria.where("date").lte(new Date())));
        //时间>=传入时间
        operations.add(Aggregation.match(Criteria.where("date").gte(new Date())));
        if (operations.size() > 0) {
            Aggregation aggregationCount = Aggregation.newAggregation(operations);
            AggregationResults<Entity> resultsCount = mongoTemplate.aggregate(aggregationCount, COLLECTION_NAME, Entity.class);
            count = resultsCount.getMappedResults().size();
        } else {
            List<Entity> list = mongoTemplate.findAll(Entity.class);
            count = list.size();
        }

        operations.add(Aggregation.skip((long) pageNum * pageSize));
        operations.add(Aggregation.limit(pageSize));
        operations.add(Aggregation.sort(Sort.Direction.DESC, "updateTime"));
        Aggregation aggregation = Aggregation.newAggregation(operations);
        AggregationResults<Entity> results = mongoTemplate.aggregate(aggregation, COLLECTION_NAME, Entity.class);

        Map<String, Object> data = new HashMap<>(3);
        Long totalPage = count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
        //内容
        data.put("rows", results.getMappedResults());
        //总数
        data.put("total", count);
        //总页数
        data.put("totalPage", totalPage);
        return data;
    }


}
